iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Web 3

當 APP develop 遇上 web3 與 Metaverse 浪潮 系列 第 28

DAY 28 [Day 貳拾捌] 來開發元宇宙中藥鋪吧16 - 中藥包NFT?場景編輯工具

  • 分享至 

  • xImage
  •  

利用

OrbitControls
TransformControls
搭配
zustand 跨階成組件 狀態管理
lamina 控制面板

import React, { createContext, useContext, Suspense, useEffect, useRef, useState } from 'react'
import { Canvas } from '@react-three/fiber'
import { OrbitControls, TransformControls, useCursor, Text, Html } from '@react-three/drei'
// import create from 'zustand'
import { Popconfirm } from 'antd'
import 'antd/dist/antd.css'

import { useTargetStore } from '../store/Store'

export function NFTBox({ children, ...props }) {
  const setTarget = useTargetStore((state) => state.setTarget)
  const [hovered, setHovered] = useState(false)
  useCursor(hovered)

  const [position, setPosition] = useState([3, 3, 60])
  const [rotation, setRotation] = useState([0, 0, 0])
  const [scale, setScale] = useState([1, 1, 1])
  const [select, setSelect] = useState(false)
  // 相似於 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    // 使用瀏覽器 API 更新文件標題
    // document.title = `You clicked ${count} times`;
    if (props.position) {
      setPosition(props.position)
    }
    if (props.rotation) {
      setRotation(props.rotation)
    }
    if (props.scale) {
      setScale(props.scale)
    }
    // console.log(props.position)
  }, [props])

  return (
    <group {...props} position={position} rotation={rotation} scale={scale}>
      <mesh
        visible={hovered}
        // position={[0, 0, 0]}
        // rotate={props.rotate}

        onClick={(e) => {
          e.stopPropagation() //It functions just like the dom does, except there is raycasting involved. In order to prevent a mouse event from "propagating" downward, you must "stopPropagation()".
          // e.stopImmediatePropagation()
          // console.log('滑鼠右鍵', e.delta)
          // console.log('滑鼠右鍵', e)

          if (e.button === 2) {
            //如果button=1(滑鼠左鍵),button=2(滑鼠右鍵),button=0(滑鼠中間鍵)
          }
          setTarget(e.object.parent)
          // console.log(e.object.parent)
          // setTarget(e.object)
          // console.log(e.object)
          setSelect(!select)
        }}
        // onClick={(e) => console.log('click')}
        onContextMenu={(e) => console.log('context menu')}
        onDoubleClick={(e) => console.log('double click')}
        onWheel={(e) => console.log('wheel spins')}
        onPointerUp={(e) => console.log('up')}
        onPointerDown={(e) => console.log('down')}
        // onPointerOver={(e) => console.log('over')}
        // onPointerOut={(e) => console.log('out')}
        onPointerEnter={(e) => console.log('enter')} // see note 1
        onPointerLeave={(e) => console.log('leave')} // see note 1
        // onPointerMove={(e) => console.log('move')}
        // onPointerMissed={() => console.log('missed')}
        // onUpdate={(self) => console.log('props have been updated')}

        // onPointerDown={(e) => {
        //   // Only the mesh closest to the camera will be processed
        //   e.stopPropagation()
        //   // You may optionally capture the target
        //   e.target.setPointerCapture(e.pointerId)
        //   // console.log('onPointerDown')
        // }}
        // onPointerUp={(e) => {
        //   e.stopPropagation()
        //   // Optionally release capture
        //   e.target.releasePointerCapture(e.pointerId)
        //   // console.log('onPointerUp')
        // }}
        // // onDoubleClick={setSelect(false)}
        onPointerOver={(e) => {
          // Only the mesh closest to the camera will be processed
          e.stopPropagation()
          // You may optionally capture the target
          e.target.setPointerCapture(e.pointerId)
          setHovered(true)
        }}
        onPointerOut={(e) => {
          e.stopPropagation()
          // Optionally release capture
          e.target.releasePointerCapture(e.pointerId)
          setHovered(false)
        }}
        scale={10}>
        <boxGeometry />
        {/* <meshPhongMaterial color="blue" opacity={0.1} transparent /> */}
        <meshStandardMaterial transparent={true} opacity={0.5} color="orange" />

        {hovered && (
          <Html distanceFactor={0.25} position={[-0.5, 1, 0.5]}>
            <div className="tooltip">|{props.name}</div>
          </Html>
        )}
        {/* {select && (
          <Html distanceFactor={0.25} position={[-0.65, 1.7, 0.5]}>
            <div className="tooltip">
              Setting
              <br />
              OK NO
            </div>
          </Html>
        )} */}
      </mesh>
      {children}
    </group>
  )
}

//TODO不傳透
//https://blog.csdn.net/weixin_41077029/article/details/108616264?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ETopBlog-1.topblog&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ETopBlog-1.topblog&utm_relevant_index=1
export function GUCBox(props) {
  const setTarget = useTargetStore((state) => state.setTarget)
  const [hovered, setHovered] = useState(false)
  useCursor(hovered)

  const [position, setPosition] = useState([3, 3, 60])
  const [rotation, setRotation] = useState([0, 0, 0])
  const [scale, setScale] = useState([1, 1, 1])
  const [select, setSelect] = useState(false)

  // 相似於 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    // 使用瀏覽器 API 更新文件標題
    // document.title = `You clicked ${count} times`;
    if (props.position) {
      setPosition(props.position)
    }
    if (props.rotation) {
      setRotation(props.rotation)
    }
    if (props.scale) {
      setScale(props.scale)
    }
    console.log(props.position)
  }, [props])

  return (
    <group {...props} position={position} rotation={rotation} scale={scale}>
      <mesh
        // position={[0, 0, 0]}
        // rotate={props.rotate}
        scale={5}
        onClick={(e) => {
          setTarget(e.object)
          setSelect(true)
        }}
        onDoubleClick={setSelect(false)}
        onPointerOver={() => setHovered(true)}
        onPointerOut={() => setHovered(false)}>
        <boxGeometry />
        <meshStandardMaterial color="orange" />
      </mesh>
    </group>
  )
}

// function OpConfirm() {
//   return (
//     <Html center>
//       <Popconfirm title="Are you sure you want to leave?" onConfirm={true} okText="Yes" cancelText="No">
//         <a href="#">{'name'}</a>
//       </Popconfirm>
//     </Html>
//   )
// }

function Dodecahedron({ time, ...props }) {
  return (
    <mesh {...props}>
      <dodecahedronGeometry />
      <meshStandardMaterial roughness={0.75} emissive="#404057" />
      <Html distanceFactor={10}>
        <div class="content">
          hello <br />
          world
        </div>
      </Html>
    </mesh>
  )
}


上一篇
[Day 貳拾柒] 來開發元宇宙中藥鋪吧15 - 中藥包NFT?丟進去場景吧
下一篇
DAY 29 [Day 貳拾玖] 來開發元宇宙中藥鋪吧17 - 虛擬座標系統
系列文
當 APP develop 遇上 web3 與 Metaverse 浪潮 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言